/*------------------------------------------------------------------------------
#
#	Apple Macintosh Developer Technical Support
#
#	MultiFinder-Aware Simple TextEdit Sample Application
#
#	CPlusTESample
#
#	TDocument.h		-	C++ source
#
#	Copyright © 1989 Apple Computer, Inc.
#	All rights reserved.
#
#	Versions:	
#			1.00 					04/89
#
#	Components:
#			CPlusTESample.make		April 1, 1989
#			TApplicationCommon.h	April 1, 1989
#			TApplication.h			April 1, 1989
#			TDocument.h				April 1, 1989
#			TECommon.h				April 1, 1989
#			TESample.h				April 1, 1989
#			TEDocument.h			April 1, 1989
#			TApplication.cp			April 1, 1989
#			TDocument.cp			April 1, 1989
#			TESample.cp				April 1, 1989
#			TEDocument.cp			April 1, 1989
#			TESampleGlue.a			April 1, 1989
#			TApplication.r			April 1, 1989
#			TESample.r				April 1, 1989
#
#	CPlusTESample is an example application that demonstrates
#	how to initialize the commonly used toolbox managers,
#	operate successfully under MultiFinder, handle desk
#	accessories and create, grow, and zoom windows. The
#	fundamental TextEdit toolbox calls and TextEdit autoscroll
#	are demonstrated. It also shows how to create and maintain
#	scrollbar controls. 
#
#	This version of TESample has been substantially reworked in
#	C++ to show how a "typical" object oriented program could
#	be written. To this end, what was once a single source code
#	file has been restructured into a set of classes which
#	demonstrate the advantages of object-oriented programming.
#
------------------------------------------------------------------------------*/

#ifndef TDocument_Defs
#define TDocument_Defs

// Include necessary interface files
#include <Types.h>
#include <QuickDraw.h>

const long kMaxSleepTime = 60;	// 1 second worth of ticks

// we derive from handle object to prevent fragmentation
class TDocument : HandleObject {
protected:
	WindowPtr fDocWindow;

public:
	TDocument(short resID);		// our constructor - creates window using resID as template
	virtual ~TDocument();		// our destructor - disposes of window

	// you will need to override these in your subclasses,
	// since they are do-nothing routines by default...
	virtual void DoZoom(short partCode) {}
	virtual void DoGrow(EventRecord* theEvent) {}
	virtual void DoContent(EventRecord* theEvent) {}
	virtual void DoKeyDown(EventRecord* theEvent) {}
	virtual void DoActivate(Boolean becomingActive) {}
	virtual void DoUpdate(void) {}
	// file handling routines
	virtual void DoOpen(void) {};
	virtual void DoClose(void) { delete this; };	// by default, we just delete ourself
	virtual void DoSave(void) {};
	virtual void DoSaveAs(void) {};
	virtual void DoRevert(void) {};
	virtual void DoPrint(void) {};
	// do standard edit menu actions
	virtual void DoUndo(void) {};
	virtual void DoCut(void) {};
	virtual void DoCopy(void) {};
	virtual void DoPaste(void) {};
	virtual void DoClear(void) {};
	virtual void DoSelectAll(void) {};

	// idle time routines: you can use these to do cursor handling,
	// TE caret blinking, marquee effects, etc...
	virtual void DoIdle(void) {};
	virtual unsigned long CalcIdle(void) { return kMaxSleepTime; };	// by default, we don't need idle
	virtual void AdjustCursor(Point where) {};			// where is in local coords

	// query state of document - useful for adjusting menu state
	virtual Boolean HaveUndo(void) { return false; };
	virtual Boolean HaveSelection(void) { return false; };
	virtual Boolean HavePaste(void) { return false; };
	virtual Boolean CanClose(void) { return true; };
	virtual Boolean CanSave(void) { return false; };
	virtual Boolean CanSaveAs(void) { return true; };
	virtual Boolean CanRevert(void) { return false; };
	virtual Boolean CanPrint(void) { return false; };

	// utility routine to get window pointer for document
	inline WindowPtr GetDocWindow(void) { return fDocWindow; }
};

// TDocumentLink is a simple utility class which is used by
// the TDocumentList class below. You cannot allocate
// objects of this type yourself, since its constructor
// is private. We get around this for TDocumentList by
// making it a "friend" of this class. This is a handy
// trick.
class TDocumentLink {
	friend class TDocumentList;

	TDocumentLink*			fNext;	// the link to the next document
	TDocument*				fDoc;	// the document this link refers to

	// our constructor. Note that it can take args for convenience,
	// but that they default to nil.
	TDocumentLink(TDocumentLink *n = nil, TDocument *v = nil);

	// implementation of our TDocumentLink routines is done inline, for speed
	inline TDocumentLink*	GetNext() { return fNext; };
	inline TDocument* 		GetDoc() { return fDoc; };
	inline void				SetNext(TDocumentLink* aLink) { fNext = aLink; };
	inline void 			SetDoc(TDocument* aDoc) { fDoc = aDoc; };
};

// TDocumentList is a simple linked list of documents, implemented C++
// style. I could have made a general linked list class & just made
// this a subclass. This would have been a more general (and more
// object-oriented) solution, but I did it from scratch in a futile
// attempt at keeping the size of this program at a reasonable level.
class TDocumentList {
	TDocumentLink*	fDocList;	// the first link in our list
	int				fNumDocs;	// the number of elements in the list

public:
	TDocumentList(void);	// our constructor

	virtual void		AddDoc(TDocument* doc);
	virtual void		RemoveDoc(TDocument* doc);
	// find the TDocument associated with the window
	virtual TDocument*	FindDoc(WindowPtr window);
	// return number of active documents
	inline int			NumDocs() { return fNumDocs; }
};

#endif TDocument_Defs
